package com.glsc.ngateway.common.base.dto.opmanage.report.subscribe;

import com.alibaba.fastjson.JSON;
import com.glsc.ngateway.common.base.domain.mysql.opmanage.report.subscribe.UserReportSubscribe;
import com.glsc.ngateway.common.base.dto.opmanage.report.auth.UserBaseInfoDto;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import smartbi.sdk.service.simplereport.NameValuePair;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;

/**
 * @author: qiyr
 * @date: 2022/6/8 17:13
 * @description: 用户报表订阅Dto
 */
public class UserReportSubscribeDto extends UserReportSubscribe {

    private static final String SUBSCRIBE_INFO_SEPARATOR = ",";

    private List<UserBaseInfoDto> subscribeInfoList;

    private List<ReportParamConfigDto> reportParamList;

    public UserReportSubscribeDto() {
    }

    public UserReportSubscribeDto(UserReportSubscribe subscribe) {
        super(subscribe.getId(), subscribe.getReportId(), subscribe.getReportName(), subscribe.getTaskFreq(),
                subscribe.getTaskTime(), subscribe.getTitleName(), subscribe.getSubscriber(), subscribe.getUsername(),
                subscribe.getUserEmail(), subscribe.getReportParam(), subscribe.getAttachmentFilename(),
                subscribe.getAttachmentType(), subscribe.getAttachmentMode(), subscribe.getOperator(),
                subscribe.getCreateTime(), subscribe.getUpdateTime());
        this.setDefaultAttachmentType(subscribe.getDefaultAttachmentType());
        this.setAttachmentTypeStatus(subscribe.getAttachmentTypeStatus());
        this.setReportParamList(toReportParamConfigDtoList(subscribe.getReportParam()));
        this.setReportParam(null);
    }

    public UserReportSubscribe toUserReportSubscribe() {
        UserReportSubscribe userReportSubscribe = new UserReportSubscribe(this.getId(),
                this.getReportId(), this.getReportName(), this.getTaskFreq(), this.getTaskTime(),
                this.getTitleName(), this.getSubscriber(), this.getUsername(), this.getUserEmail(),
                this.getReportParam(), this.getAttachmentFilename(), this.getAttachmentType(),
                this.getAttachmentMode(), this.getOperator(), this.getCreateTime(), this.getUpdateTime());
        if (!CollectionUtils.isEmpty(subscribeInfoList)) {
            StringJoiner subscribes = new StringJoiner(SUBSCRIBE_INFO_SEPARATOR);
            StringJoiner usernames = new StringJoiner(SUBSCRIBE_INFO_SEPARATOR);
            StringJoiner userEmails = new StringJoiner(SUBSCRIBE_INFO_SEPARATOR);
            subscribeInfoList.forEach(item -> {
                subscribes.add(item.getUsername());
                usernames.add(item.getName());
                userEmails.add(item.getEmail());
            });
            userReportSubscribe.setSubscriber(subscribes.toString());
            userReportSubscribe.setUsername(usernames.toString());
            userReportSubscribe.setUserEmail(userEmails.toString());
        }
        List<ReportParamDto> paramDtoList = this.constructReportParamDtoList();
        userReportSubscribe.setParamList(paramDtoList);
        userReportSubscribe.setReportParam(constructReportParam(paramDtoList));
        return userReportSubscribe;
    }

    public List<UserReportSubscribe> toUserReportSubscribeList() {
        List<UserReportSubscribe> userReportSubscribeList = new ArrayList<>();
        List<ReportParamDto> paramDtoList = this.constructReportParamDtoList();
        String reportParam = constructReportParam(paramDtoList);
        subscribeInfoList.forEach(item -> {
            UserReportSubscribe userReportSubscribe = new UserReportSubscribe(this.getId(),
                    this.getReportId(), this.getReportName(), this.getTaskFreq(), this.getTaskTime(),
                    this.getTitleName(), this.getSubscriber(), this.getUsername(), this.getUserEmail(),
                    this.getReportParam(), this.getAttachmentFilename(), this.getAttachmentType(),
                    this.getAttachmentMode(), this.getOperator(), this.getCreateTime(), this.getUpdateTime());
            userReportSubscribe.setSubscriber(item.getUsername());
            userReportSubscribe.setUsername(item.getName());
            userReportSubscribe.setUserEmail(item.getEmail());
            userReportSubscribe.setReportParam(reportParam);
            userReportSubscribe.setParamList(paramDtoList);
            userReportSubscribeList.add(userReportSubscribe);
        });
        return userReportSubscribeList;
    }

    public List<UserBaseInfoDto> getSubscribeInfoList() {
        return subscribeInfoList;
    }

    public void setSubscribeInfoList(List<UserBaseInfoDto> subscribeInfoList) {
        this.subscribeInfoList = subscribeInfoList;
    }

    public List<ReportParamConfigDto> getReportParamList() {
        return reportParamList;
    }

    public void setReportParamList(List<ReportParamConfigDto> reportParamList) {
        this.reportParamList = reportParamList;
    }

    private List<ReportParamDto> constructReportParamDtoList() {
        List<ReportParamDto> dtoList = new ArrayList<>();
        this.getReportParamList().forEach(item -> dtoList.add(item.toReportParamDto()));
        return dtoList;
    }

    private String constructReportParam(List<ReportParamDto> dtoList) {
        if (CollectionUtils.isEmpty(dtoList)) {
            return null;
        }
        return JSON.toJSONString(dtoList);
    }

    private List<ReportParamConfigDto> toReportParamConfigDtoList(String reportParam) {
        if (!StringUtils.hasText(reportParam)) {
            return Collections.EMPTY_LIST;
        }
        List<ReportParamDto> paramDtoList = JSON.parseArray(reportParam, ReportParamDto.class);
        List<ReportParamConfigDto> result = new ArrayList<>();
        paramDtoList.forEach(item -> {
            ReportParamConfigDto dto = new ReportParamConfigDto();
            dto.setParamKey(item.getName());
            dto.setReportParamValueMap(item.getNameValuePairList().stream().collect(
                    Collectors.toMap(NameValuePair::getValue, NameValuePair::getName)));
            result.add(dto);
        });
        return result;
    }
}
